{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `constexpr` vs `consteval`（C++20），以及 C++17 的模拟方法\n",
    "\n",
    "| 关键词                    | 定义/语义                                                    | 何时执行                                                     | C++17 状态                                                   |\n",
    "| ------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |\n",
    "| `constexpr` 函数          | 可在编译期或运行期调用；若所有实参可在编译期求值，则结果常量表达式 | 取决于调用点：若编译期上下文需要常量，则编译期计算，否则运行时 | 已存在，可标记函数                                           |\n",
    "| `consteval` 函数（C++20） | 必须在编译期调用，生成编译期常量，任何运行期调用都会报错     | 强制编译期                                                   | C++17 无；可用 `constexpr` + `static_assert`/ `if constexpr` 模拟检查 |\n",
    "\n",
    "**C++17 模拟 consteval**：可写一个 `constexpr` 函数，并在使用处包裹 `static_assert` 保证某些路径仅在编译期调用；或者用 `struct` 模板 + `constexpr` 变量确保只在常量表达式上下文中实例化。不过无法完全阻止运行期调用（没有语言级保证）。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## **`constexpr` 函数在日志/配置解析中的用法**\n",
    "\n",
    "- 编译期生成查表、验证常量配置；`constexpr` 解析 JSON 片段生成结构（受限），或构造静态日志标签避免运行时拼接。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `std::integer_sequence` / `std::index_sequence` 的作用\n",
    "\n",
    "- `std::integer_sequence<T, I...>`：保存一组编译期整数，用于模板展开、参数包“解包”。\n",
    "- `std::index_sequence<I...>`：`integer_sequence<std::size_t, I...>` 的别名，最常用于生成 0..N-1 的索引。\n",
    "\n",
    "**典型用途**：在可变参数模板中，将 `std::tuple` 展开成函数参数；或在编译期遍历数组、调用多组函数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "template <typename Tuple, std::size_t... I>\n",
    "void apply_impl(Tuple&& tup, std::index_sequence<I...>) {\n",
    "    some_function(std::get<I>(std::forward<Tuple>(tup))...);\n",
    "}\n",
    "\n",
    "template <typename Tuple>\n",
    "void my_apply(Tuple&& tup) {\n",
    "    constexpr auto N = std::tuple_size_v<std::decay_t<Tuple>>;\n",
    "    apply_impl(std::forward<Tuple>(tup), std::make_index_sequence<N>{});\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 编译期计算斐波那契：`constexpr` vs 模板递归\n",
    "\n",
    "`constexpr` 版本（C++14 起支持循环）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "constexpr unsigned fib_constexpr(unsigned n) {\n",
    "    unsigned a = 0, b = 1;\n",
    "    while (n--) {\n",
    "        unsigned tmp = a + b;\n",
    "        a = b;\n",
    "        b = tmp;\n",
    "    }\n",
    "    return a;\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **优点**：逻辑清晰，可调试，易与运行时代码共用。\n",
    "- **缺点**：编译期计算需要被常量上下文触发（如 `constexpr auto x = fib_constexpr(10);`），对更复杂计算可能编译慢。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "模板递归版本（`std::integral_constant`）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "template <unsigned N>\n",
    "struct Fib : std::integral_constant<unsigned, Fib<N-1>::value + Fib<N-2>::value> {};\n",
    "\n",
    "template <>\n",
    "struct Fib<0> : std::integral_constant<unsigned, 0> {};\n",
    "\n",
    "template <>\n",
    "struct Fib<1> : std::integral_constant<unsigned, 1> {};\n",
    "\n",
    "constexpr unsigned v = Fib<10>::value;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **优点**：完全在类型系统内计算，适配需要模板常量的场景。\n",
    "- **缺点**：写法繁琐，递归深度受限，报错信息难读，编译耗时/耗内存更大。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 常见类型萃取（type traits）\n",
    "\n",
    "标准库 `<type_traits>` 提供大量 trait，用于在编译期检查类型性质或做条件分派。常用示例：\n",
    "\n",
    "- 类型关系：`std::is_same_v`, `std::is_base_of_v`, `std::is_convertible_v`\n",
    "- 类型属性：`std::is_const_v`, `std::is_reference_v`, `std::is_pointer_v`\n",
    "- 构造/赋值能力：`std::is_copy_constructible_v`, `std::is_trivially_copyable_v`, `std::is_move_assignable_v`\n",
    "- 数值性质：`std::is_integral_v`, `std::is_floating_point_v`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "static_assert(std::is_same_v<int, std::remove_const_t<const int>>);\n",
    "static_assert(std::is_trivially_copyable_v<int>);\n",
    "static_assert(!std::is_trivially_copyable_v<std::string>);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这些 trait 常配合 `std::enable_if_t`, `if constexpr`, `concepts`（C++20）等用来控制模板实例化或选择分支。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `decltype(auto)` 的推导规则 vs `auto`\n",
    "\n",
    "- `auto` 推导结果类似“剥离引用、但保留顶层 const”，忽略引用折叠。\n",
    "- `decltype(auto)` 遵循 `decltype` 的规则（保留引用/值类别）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "int x = 0;\n",
    "int& rx = x;\n",
    "\n",
    "// auto\n",
    "auto a = rx;           // a 推导为 int（引用被剥离）\n",
    "auto&& b = rx;         // b 为 int&（引用折叠）\n",
    "\n",
    "// decltype(auto)\n",
    "decltype(auto) c = rx; // c 推导为 int&（保持引用）\n",
    "decltype(auto) d = (rx); // d 也是 int&，因为 decltype((expr)) -> T&"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**用途**：在模板或转发函数中返回表达式结果时，`decltype(auto)` 可精确保留原值类别与 const/引用特性，避免不必要的拷贝或 cv 限定丢失。\n",
    "\n",
    "------\n",
    "\n",
    "如需进一步示例（如利用 `integer_sequence` 实现 `tuple` 到 `struct` 的映射、使用 `constexpr` 计算数组、或更多 type trait 应用），欢迎继续提问。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **避免模板编译时间爆炸与调试技巧**\n",
    "\n",
    "- 拆分元算法（`type_list` 工具、`constexpr if`）；使用概念或 `enable_if` 限制实例数量。\n",
    "- 调试：`static_assert` 打印类型（`typeid(T).name()`）、`clang -ftemplate-backtrace-limit`、`-fdiagnostics-color`。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **`constexpr + std::array` 查表优化**\n",
    "\n",
    "- 编译期生成 LUT（如 `constexpr std::array<int,256> sines = []{...}();`），运行时 O(1) 查，避免重复计算。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **调优模板实例数量**\n",
    "\n",
    "- `-frepo`（GCC）记录模板实例；或使用 LTO/`-fno-implicit-templates` 配合显式实例化。\n",
    "- Dead code elimination：LTO、`--gc-sections` 移除未引用模板实例。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **热更新模块支持**\n",
    "\n",
    "- 插件架构（`dlopen` + 工厂函数）；接口使用稳定 ABI。\n",
    "- 通过脚本语言（Lua/Python）绑定 C++ 基础设施，实现逻辑热替换。\n",
    "- 使用 `std::function`/`std::variant` 存储回调，Reload 时替换实现。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++17",
   "language": "C++17",
   "name": "xcpp17"
  },
  "language_info": {
   "name": "C++17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
